package com.pick.base.util;

import cn.hutool.core.util.StrUtil;

/**
 * 数据脱敏工具类
 * 用于敏感信息的脱敏处理
 *
 * @author pick
 * @since 2024-01-01
 */
public class DesensitizeUtil {

    private static final String MASK_CHAR = "*";

    /**
     * 手机号脱敏
     * 保留前3位和后4位，中间用*代替
     * 例：138****1234
     */
    public static String phone(String phone) {
        if (StrUtil.isBlank(phone) || phone.length() < 7) {
            return phone;
        }
        return phone.substring(0, 3) + MASK_CHAR.repeat(4) + phone.substring(phone.length() - 4);
    }

    /**
     * 邮箱脱敏
     * 保留@前的前2位和@后的全部，中间用*代替
     * 例：ab***@example.com
     */
    public static String email(String email) {
        if (StrUtil.isBlank(email) || !email.contains("@")) {
            return email;
        }
        
        String[] parts = email.split("@");
        if (parts.length != 2 || parts[0].length() < 3) {
            return email;
        }
        
        String username = parts[0];
        String domain = parts[1];
        
        return username.substring(0, 2) + MASK_CHAR.repeat(username.length() - 2) + "@" + domain;
    }

    /**
     * 身份证号脱敏
     * 保留前6位和后4位，中间用*代替
     * 例：110101********1234
     */
    public static String idCard(String idCard) {
        if (StrUtil.isBlank(idCard) || idCard.length() < 10) {
            return idCard;
        }
        return idCard.substring(0, 6) + MASK_CHAR.repeat(8) + idCard.substring(idCard.length() - 4);
    }

    /**
     * 银行卡号脱敏
     * 保留前4位和后4位，中间用*代替
     * 例：6222********1234
     */
    public static String bankCard(String bankCard) {
        if (StrUtil.isBlank(bankCard) || bankCard.length() < 8) {
            return bankCard;
        }
        return bankCard.substring(0, 4) + MASK_CHAR.repeat(bankCard.length() - 8) + bankCard.substring(bankCard.length() - 4);
    }

    /**
     * 姓名脱敏
     * 保留第一个字符，其余用*代替
     * 例：张**
     */
    public static String name(String name) {
        if (StrUtil.isBlank(name) || name.length() < 2) {
            return name;
        }
        return name.substring(0, 1) + MASK_CHAR.repeat(name.length() - 1);
    }

    /**
     * 地址脱敏
     * 保留前6个字符，其余用*代替
     * 例：北京市朝阳区******
     */
    public static String address(String address) {
        if (StrUtil.isBlank(address) || address.length() < 8) {
            return address;
        }
        return address.substring(0, 6) + MASK_CHAR.repeat(address.length() - 6);
    }

    /**
     * 密码脱敏
     * 全部用*代替
     */
    public static String password(String password) {
        if (StrUtil.isBlank(password)) {
            return password;
        }
        return MASK_CHAR.repeat(password.length());
    }

    /**
     * IP地址脱敏
     * 保留前两段，后两段用*代替
     * 例：192.168.*.*
     */
    public static String ipAddress(String ip) {
        if (StrUtil.isBlank(ip) || !ip.contains(".")) {
            return ip;
        }
        
        String[] parts = ip.split("\\.");
        if (parts.length != 4) {
            return ip;
        }
        
        return parts[0] + "." + parts[1] + ".*.* ";
    }

    /**
     * 自定义脱敏
     * @param str 原字符串
     * @param start 保留开始位置
     * @param end 保留结束位置
     * @return 脱敏后的字符串
     */
    public static String custom(String str, int start, int end) {
        if (StrUtil.isBlank(str) || start < 0 || end < 0 || start + end >= str.length()) {
            return str;
        }
        
        String prefix = str.substring(0, start);
        String suffix = str.substring(str.length() - end);
        String middle = MASK_CHAR.repeat(str.length() - start - end);
        
        return prefix + middle + suffix;
    }

    /**
     * 根据类型进行脱敏
     * @param data 原数据
     * @param type 脱敏类型
     * @return 脱敏后的数据
     */
    public static String desensitize(String data, DesensitizeType type) {
        if (StrUtil.isBlank(data)) {
            return data;
        }
        
        return switch (type) {
            case PHONE -> phone(data);
            case EMAIL -> email(data);
            case ID_CARD -> idCard(data);
            case BANK_CARD -> bankCard(data);
            case NAME -> name(data);
            case ADDRESS -> address(data);
            case PASSWORD -> password(data);
            case IP_ADDRESS -> ipAddress(data);
            default -> data;
        };
    }

    /**
     * 脱敏类型枚举
     */
    public enum DesensitizeType {
        /**
         * 手机号
         */
        PHONE,
        
        /**
         * 邮箱
         */
        EMAIL,
        
        /**
         * 身份证号
         */
        ID_CARD,
        
        /**
         * 银行卡号
         */
        BANK_CARD,
        
        /**
         * 姓名
         */
        NAME,
        
        /**
         * 地址
         */
        ADDRESS,
        
        /**
         * 密码
         */
        PASSWORD,
        
        /**
         * IP地址
         */
        IP_ADDRESS
    }
}